# ==============================================================================
# Happy Mall Monorepo Makefile with Go Workspace Support
# ==============================================================================

# 定义全局 Makefile 变量方便后面引用
COMMON_SELF_DIR := $(dir $(lastword $(MAKEFILE_LIST)))
ROOT_DIR := $(abspath $(shell cd $(COMMON_SELF_DIR)/ && pwd -P))
OUTPUT_DIR := $(ROOT_DIR)/_output

# 定义版本相关变量
VERSION_PACKAGE=gitee.com/monkeyPP/happy-mall/pkg/version

ifeq ($(origin VERSION), undefined)
VERSION := $(shell git describe --tags --always --match='v*')
endif

GIT_TREE_STATE:="dirty"
ifeq (, $(shell git status --porcelain 2>/dev/null))
	GIT_TREE_STATE="clean"
endif
GIT_COMMIT:=$(shell git rev-parse HEAD)

GO_LDFLAGS += \
	-X $(VERSION_PACKAGE).GitVersion=$(VERSION) \
	-X $(VERSION_PACKAGE).GitCommit=$(GIT_COMMIT) \
	-X $(VERSION_PACKAGE).GitTreeState=$(GIT_TREE_STATE) \
	-X $(VERSION_PACKAGE).BuildDate=$(shell date -u +'%Y-%m-%dT%H:%M:%SZ')

# 定义服务列表
SERVICES := userservice orderservice productservice
SERVICE_DIRS := $(addprefix services/,$(SERVICES))

# 定义模块列表
MODULES := pkg shared api $(SERVICE_DIRS)

# ==============================================================================
# 默认目标
# ==============================================================================

.PHONY: all
all: format lint build ## 构建所有组件

# ==============================================================================
# Go Workspace 管理
# ==============================================================================

.PHONY: workspace-init
workspace-init: ## 初始化 Go workspace
	@echo "🔧 初始化 Go workspace..."
	go work init
	go work use $(MODULES)

.PHONY: workspace-sync
workspace-sync: ## 同步 workspace
	@echo "🔄 同步 Go workspace..."
	go work sync

.PHONY: workspace-use
workspace-use: ## 添加所有模块到 workspace
	@echo "📦 添加模块到 workspace..."
	go work use $(MODULES)

# ==============================================================================
# 依赖管理
# ==============================================================================

.PHONY: tidy
tidy: ## 整理所有模块的依赖
	@echo "🧹 整理所有模块依赖..."
	@for module in $(MODULES); do \
		echo "📦 整理 $$module 依赖..."; \
		cd $(ROOT_DIR)/$$module && go mod tidy; \
	done

.PHONY: download
download: ## 下载所有模块的依赖
	@echo "⬇️  下载所有模块依赖..."
	@for module in $(MODULES); do \
		echo "📦 下载 $$module 依赖..."; \
		cd $(ROOT_DIR)/$$module && go mod download; \
	done

# ==============================================================================
# 构建
# ==============================================================================

.PHONY: build
build: $(addprefix build-,$(SERVICES)) ## 构建所有服务

.PHONY: build-userservice
build-userservice: tidy-userservice ## 构建用户服务
	@echo "🔨 构建 userservice 服务..."
	@cd $(ROOT_DIR)/services/userservice && \
	go build -v -ldflags "$(GO_LDFLAGS)" -o $(OUTPUT_DIR)/userservice ./cmd/main.go
	@echo "✅ userservice 服务构建完成"

.PHONY: build-orderservice
build-orderservice: tidy-orderservice ## 构建订单服务
	@echo "🔨 构建 orderservice 服务..."
	@mkdir -p $(OUTPUT_DIR)
	@cd $(ROOT_DIR)/services/orderservice && \
	echo 'package main; import "fmt"; func main() { fmt.Println("Order service placeholder") }' > cmd/main.go 2>/dev/null || true
	@cd $(ROOT_DIR)/services/orderservice && \
	go build -v -ldflags "$(GO_LDFLAGS)" -o $(OUTPUT_DIR)/orderservice ./cmd/main.go
	@echo "✅ orderservice 服务构建完成"

.PHONY: build-productservice
build-productservice: tidy-productservice ## 构建产品服务
	@echo "🔨 构建 productservice 服务..."
	@mkdir -p $(OUTPUT_DIR)
	@cd $(ROOT_DIR)/services/productservice && \
	echo 'package main; import "fmt"; func main() { fmt.Println("Product service placeholder") }' > cmd/main.go 2>/dev/null || true
	@cd $(ROOT_DIR)/services/productservice && \
	go build -v -ldflags "$(GO_LDFLAGS)" -o $(OUTPUT_DIR)/productservice ./cmd/main.go
	@echo "✅ productservice 服务构建完成"

# 为每个服务创建单独的 tidy 目标
.PHONY: tidy-userservice tidy-orderservice tidy-productservice
tidy-userservice:
	@echo "🧹 整理 userservice 依赖..."
	@cd $(ROOT_DIR)/services/userservice && go mod tidy

tidy-orderservice:
	@echo "🧹 整理 orderservice 依赖..."
	@cd $(ROOT_DIR)/services/orderservice && go mod tidy

tidy-productservice:
	@echo "🧹 整理 productservice 依赖..."
	@cd $(ROOT_DIR)/services/productservice && go mod tidy

# ==============================================================================
# 测试
# ==============================================================================

.PHONY: test
test: ## 运行所有测试
	@echo "🧪 运行所有模块测试..."
	@for module in $(MODULES); do \
		echo "🧪 测试 $$module..."; \
		cd $(ROOT_DIR)/$$module && go test ./... -v; \
	done

.PHONY: test-userservice
test-userservice: ## 运行用户服务测试
	@echo "🧪 运行 userservice 测试..."
	@cd $(ROOT_DIR)/services/userservice && go test ./... -v

.PHONY: test-orderservice
test-orderservice: ## 运行订单服务测试
	@echo "🧪 运行 orderservice 测试..."
	@cd $(ROOT_DIR)/services/orderservice && go test ./... -v

.PHONY: test-productservice
test-productservice: ## 运行产品服务测试
	@echo "🧪 运行 productservice 测试..."
	@cd $(ROOT_DIR)/services/productservice && go test ./... -v

.PHONY: test-integration
test-integration: ## 运行集成测试
	@echo "🧪 运行集成测试..."
	@cd $(ROOT_DIR)/tests/integration && go test ./... -v

.PHONY: test-e2e
test-e2e: ## 运行端到端测试
	@echo "🧪 运行端到端测试..."
	@cd $(ROOT_DIR)/tests/e2e && go test ./... -v

# ==============================================================================
# 代码质量
# ==============================================================================

.PHONY: format
format: ## 格式化所有 Go 代码
	@echo "🎨 格式化所有 Go 代码..."
	@for module in $(MODULES); do \
		echo "🎨 格式化 $$module..."; \
		cd $(ROOT_DIR)/$$module && gofmt -s -w .; \
	done

.PHONY: lint
lint: ## 检查所有代码
	@echo "🔍 检查所有代码..."
	@for module in $(MODULES); do \
		echo "🔍 检查 $$module..."; \
		cd $(ROOT_DIR)/$$module && golangci-lint run ./...; \
	done

# ==============================================================================
# 代码生成
# ==============================================================================

.PHONY: generate
generate: proto-gen swagger-gen ## 生成所有代码

.PHONY: proto-gen
proto-gen: ## 生成 gRPC 代码
	@echo "📡 生成 gRPC 代码..."
	@cd $(ROOT_DIR) && buf generate

.PHONY: swagger-gen
swagger-gen: ## 生成 Swagger 文档
	@echo "📚 生成 Swagger 文档..."
	@for service in $(SERVICES); do \
		if [ -d "$(ROOT_DIR)/services/$$service" ]; then \
			echo "📚 生成 $$service Swagger 文档..."; \
			cd $(ROOT_DIR)/services/$$service && swag init -g cmd/main.go --parseDependency --parseInternal; \
		fi; \
	done

# ==============================================================================
# 运行服务
# ==============================================================================

.PHONY: run-userservice
run-userservice: build-userservice ## 运行用户服务
	@echo "🚀 启动 userservice..."
	@$(OUTPUT_DIR)/userservice

.PHONY: run-orderservice
run-orderservice: build-orderservice ## 运行订单服务
	@echo "🚀 启动 orderservice..."
	@$(OUTPUT_DIR)/orderservice

.PHONY: run-productservice
run-productservice: build-productservice ## 运行产品服务
	@echo "🚀 启动 productservice..."
	@$(OUTPUT_DIR)/productservice

# ==============================================================================
# Docker
# ==============================================================================

.PHONY: docker-build
docker-build: $(addprefix docker-build-,$(SERVICES)) ## 构建所有服务的 Docker 镜像

.PHONY: docker-build-userservice
docker-build-userservice: ## 构建用户服务 Docker 镜像
	@echo "🐳 构建 userservice Docker 镜像..."
	@docker build -f services/userservice/Dockerfile -t happy-mall-userservice:$(VERSION) .

.PHONY: docker-build-orderservice
docker-build-orderservice: ## 构建订单服务 Docker 镜像
	@echo "🐳 构建 orderservice Docker 镜像..."
	@docker build -f services/orderservice/Dockerfile -t happy-mall-orderservice:$(VERSION) . || echo "⚠️  orderservice Dockerfile 不存在"

.PHONY: docker-build-productservice
docker-build-productservice: ## 构建产品服务 Docker 镜像
	@echo "🐳 构建 productservice Docker 镜像..."
	@docker build -f services/productservice/Dockerfile -t happy-mall-productservice:$(VERSION) . || echo "⚠️  productservice Dockerfile 不存在"

# ==============================================================================
# 开发环境
# ==============================================================================

.PHONY: dev-compose
dev-compose: ## 启动开发环境
	@echo "🐳 启动开发环境..."
	@docker-compose -f deployments/docker-compose/docker-compose.dev.yaml up -d

.PHONY: dev-compose-down
dev-compose-down: ## 停止开发环境
	@echo "🐳 停止开发环境..."
	@docker-compose -f deployments/docker-compose/docker-compose.dev.yaml down

.PHONY: dev-logs
dev-logs: ## 查看开发环境日志
	@docker-compose -f deployments/docker-compose/docker-compose.dev.yaml logs -f

# ==============================================================================
# 数据库管理
# ==============================================================================

.PHONY: migrate-up
migrate-up: ## 运行数据库迁移
	@echo "📊 运行数据库迁移..."
	@migrate -path deployments/migrations -database "postgres://admin:123456@localhost:5432/happy_mall?sslmode=disable" up

.PHONY: migrate-down
migrate-down: ## 回滚数据库迁移
	@echo "📊 回滚数据库迁移..."
	@migrate -path deployments/migrations -database "postgres://admin:123456@localhost:5432/happy_mall?sslmode=disable" down

# ==============================================================================
# 工具安装
# ==============================================================================

.PHONY: install-tools
install-tools: ## 安装开发工具
	@echo "🔧 安装开发工具..."
	@chmod +x tools/scripts/install-tools.sh
	@./tools/scripts/install-tools.sh

# ==============================================================================
# 清理
# ==============================================================================

.PHONY: clean
clean: ## 清理构建产物
	@echo "🧹 清理构建产物..."
	@rm -rf $(OUTPUT_DIR)
	@for module in $(MODULES); do \
		cd $(ROOT_DIR)/$$module && go clean -cache; \
	done

# ==============================================================================
# 健康检查
# ==============================================================================

.PHONY: health-check
health-check: ## 检查服务健康状态
	@echo "🏥 检查服务健康状态..."
	@curl -f http://localhost:8000/healthz || echo "❌ userservice 不可达"
	@curl -f http://localhost:8001/healthz || echo "❌ orderservice 不可达"
	@curl -f http://localhost:8002/healthz || echo "❌ productservice 不可达"

# ==============================================================================
# 帮助
# ==============================================================================

.PHONY: help
help: ## 显示帮助信息
	@echo "Happy Mall Monorepo with Go Workspace"
	@echo ""
	@echo "可用命令:"
	@awk 'BEGIN {FS = ":.*##"} /^[a-zA-Z_-]+:.*?##/ { printf "  %-20s %s\n", $$1, $$2 }' $(MAKEFILE_LIST)

# ==============================================================================
# 设置默认目标
# ==============================================================================

.DEFAULT_GOAL := help
